package com.huaxin.hxmodulesystem.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.huaxin.hxjwt.config.JwtUtils;
import com.huaxin.hxjwt.entity.JwtModel;
import com.huaxin.hxmodulesystem.common.PasswordUtil;
import com.huaxin.hxmodulesystem.dto.ResponseCode;
import com.huaxin.hxmodulesystem.dto.ResponseResult;
import com.huaxin.hxmodulesystem.dto.request.AddSysUserReqDTO;
import com.huaxin.hxmodulesystem.dto.request.SysUserLoginReqDTO;
import com.huaxin.hxmodulesystem.dto.request.UpdatePasswordReqDTO;
import com.huaxin.hxmodulesystem.dto.request.UpdateSysUserReqDTO;
import com.huaxin.hxmodulesystem.dto.response.SysUserLoginRespDTO;
import com.huaxin.hxmodulesystem.mapper.PermissionMapper;
import com.huaxin.hxmodulesystem.mapper.RolePermissionMapper;
import com.huaxin.hxmodulesystem.mapper.SysUserMapper;
import com.huaxin.hxmodulesystem.mapping.SysUserMapping;
import com.huaxin.hxmodulesystem.models.Permission;
import com.huaxin.hxmodulesystem.models.RolePermission;
import com.huaxin.hxmodulesystem.models.SysUser;
import com.huaxin.hxmodulesystem.service.SysUserService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.CacheManager;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> implements SysUserService {
    private final CacheManager cacheManager;

    private final ObjectMapper objectMapper = new ObjectMapper();

    private final ApplicationContext applicationContext;

    private final SysUserMapping sysUserMapping;

    private final PermissionMapper permissionMapper;
    private final RolePermissionMapper rolePermissionMapper;

    //新增用户
    @Override
    public ResponseResult<String> addUser(AddSysUserReqDTO in) {
        if (in == null) {
            return ResponseResult.parameterError(null, "参数错误");
        }
        if (StringUtils.isBlank(in.getUsername())) {
            return ResponseResult.parameterError(null, "用户名不能为空");
        }
        if (StringUtils.isBlank(in.getPasswordHash())) {
            return ResponseResult.parameterError(null, "密码不能为空");
        }
        if (StringUtils.isBlank(in.getEmail())) {
            return ResponseResult.parameterError(null, "邮箱不能为空");
        }
        if (StringUtils.isBlank(in.getRealName())) {
            return ResponseResult.parameterError(null, "真实姓名不能为空");
        }
        if (StringUtils.isBlank(in.getPhone())) {
            return ResponseResult.parameterError(null, "手机号不能为空");
        }
        //判断是否重复
        if (this.queryAccountExist(in.getUsername())) {
            return ResponseResult.parameterError(null, "用户名已存在");
        }
        // 使用 BCrypt 加密密码
        String hashedPassword = PasswordUtil.hashPassword(in.getPasswordHash());
        SysUser sysUser = sysUserMapping.toEntity(in);
        sysUser.setPasswordHash(hashedPassword);
        if (sysUser == null) {
            return ResponseResult.parameterError(null, "参数错误");
        }
        if (this.save(sysUser)) {
            return ResponseResult.ok("用户创建成功！");
        } else {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "用户创建失败，请稍后再试！", null);
        }
    }

    //更新用户
    @Override
    public ResponseResult<String> updateUser(UpdateSysUserReqDTO in) {
        if (StringUtils.isBlank(in.getId())) {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "获取不到用户！", null);
        }
        if (StringUtils.isBlank(in.getPhone())) {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "请输入手机号！", null);
        }
        if (StringUtils.isBlank(in.getRealName())) {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "请输入真实姓名！", null);
        }
        if (StringUtils.isBlank(in.getEmail())) {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "请输入邮箱！", null);
        }
        SysUser sysUser = this.baseMapper.selectById(in.getId());
        sysUserMapping.updateEntity(in, sysUser);
        if (this.baseMapper.updateById(sysUser) > 0) {
            return ResponseResult.ok(null);
        } else {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "修改用户信息失败，请稍后再试！", null);
        }
    }

    //删除用户
    @Override
    public ResponseResult<String> deleteUser(String userId) {
        if (StringUtils.isBlank(userId)) {
            return ResponseResult.parameterError(null, "用户ID不能为空！");
        }
        if (applicationContext.getBean(SysUserService.class).removeById(userId)) {
            return ResponseResult.ok("删除成功！");
        } else {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "删除失败！", null);
        }
    }

    //禁用用户
    @Override
    public ResponseResult<String> disableUser(String userId, Integer status, LocalDateTime lockedUntil) {
        if (StringUtils.isBlank(userId)) {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "请选择用户！", null);
        }
        SysUser users = this.baseMapper.selectById(userId);
        if (users == null) {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "用户不存在！", null);
        }
        users.setStatus(status);
        if (status == -1) {
            users.setLockedUntil(lockedUntil);
        }
        if (this.baseMapper.updateById(users) > 0) {
            return ResponseResult.ok("操作成功！");
        } else {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "操作失败，请稍后再试！", null);
        }
    }

    //获取用户列表
    @Override
    public ResponseResult<Page<SysUser>> getUserList(Integer pageNum, Integer pageSize, String search, Integer status) {
        Page<SysUser> page = new Page<>(pageNum, pageSize);
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(search)) {
            wrapper.and(wrapper1 -> wrapper1.like("real_name", search).or().like("username", search).or().like("phone", search).or().like("email", search));
        }
        if (status != null && status > -2) {
            wrapper.eq("status", status);
        }
        return ResponseResult.ok(this.baseMapper.selectPage(page, wrapper));
    }

    //获取用户信息
    @Override
    public SysUser getUserInfoById(String userId) {
        if (StringUtils.isBlank(userId)) {
            return null;
        }
        return this.baseMapper.selectById(userId);
    }

    //给用户设置角色
    @Override
    public ResponseResult<String> setUserRole(String userId, String roleId) {
        if (StringUtils.isBlank(userId)) {
            return ResponseResult.parameterError(null, "用户ID不能为空");
        }
        if (StringUtils.isBlank(roleId)) {
            return ResponseResult.parameterError(null, "角色ID不能为空");
        }
        SysUser user = this.baseMapper.selectById(userId);
        if (user == null) {
            return ResponseResult.notFound(null, "用户不存在");
        }
        user.setRoleId(roleId);
        if (this.baseMapper.updateById(user) > 0) {
            return ResponseResult.ok(null);
        } else {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "分配角色失败，请稍后再试！", null);
        }
    }

    //登录
    @Override
    public ResponseResult<SysUserLoginRespDTO> login(SysUserLoginReqDTO loginRequest) {
        // 参数校验
        if (loginRequest == null) {
            return ResponseResult.parameterError(null, "参数错误！");
        }
        if (StringUtils.isEmpty(loginRequest.getUsername())) {
            return ResponseResult.parameterError(null, "用户名不能为空！");
        }
        if (StringUtils.isEmpty(loginRequest.getPassword())) {
            return ResponseResult.parameterError(null, "密码不能为空！");
        }

        // 查询用户
        SysUser user = this.baseMapper.selectOne(
                new QueryWrapper<SysUser>().eq("username", loginRequest.getUsername())
        );

        if (user == null || !PasswordUtil.verifyPassword(loginRequest.getPassword(), user.getPasswordHash())) {
            // 统一提示，防止用户名枚举攻击
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "用户名或密码错误！", null);
        }

        // 生成 Token
        JwtModel jwtModel = new JwtModel();
        jwtModel.setUserId(user.getId());
        String token = JwtUtils.generateToken(jwtModel);

        SysUserLoginRespDTO userLoginRespDTO = new SysUserLoginRespDTO();
        userLoginRespDTO.setUser(user);
        userLoginRespDTO.setToken(token);

        // 权限处理
        if (StringUtils.isNotBlank(user.getRoleId())) {
            List<Permission> permissions = new ArrayList<>();
            String currentRoleId = user.getRoleId();

            if ("admin".equals(currentRoleId)) {
                // 管理员：获取所有后台权限（application_type = 5）
                permissions = permissionMapper.selectList(
                        new LambdaQueryWrapper<Permission>()
                                .eq(Permission::getApplicationType, 5)
                );
            } else {
                // 普通角色：先查角色-权限关联
                List<RolePermission> rolePermissions = rolePermissionMapper.selectList(
                        new LambdaQueryWrapper<RolePermission>()
                                .eq(RolePermission::getRoleId, user.getRoleId())
                );

                if (!rolePermissions.isEmpty()) {
                    List<String> permissionIds = rolePermissions.stream()
                            .map(RolePermission::getPermissionId)
                            .collect(Collectors.toList());

                    permissions = permissionMapper.selectList(
                            new LambdaQueryWrapper<Permission>()
                                    .in(Permission::getId, permissionIds)
                    );
                }
                // 若 rolePermissions 为空，则 permissions 保持为空列表
            }

            userLoginRespDTO.setPermissions(permissions); // 可以是空列表，前端好处理
        }

        return ResponseResult.ok(userLoginRespDTO);
    }

    //初始化密码
    @Override
    public ResponseResult<String> initPassword(String userId) {
        if (StringUtils.isBlank(userId)) {
            return ResponseResult.parameterError(null, "参数错误");
        }
        SysUser user = this.baseMapper.selectById(userId);
        if (user == null) {
            return ResponseResult.notFound(null, "没有找到该用户");
        }
        String hashedPassword = PasswordUtil.hashPassword("123456");
        user.setPasswordHash(hashedPassword);
        if (this.baseMapper.updateById(user) > 0) {
            return ResponseResult.ok("密码重置成功！");
        } else {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "密码重置失败！", null);
        }
    }

    //修改密码
    @Override
    public ResponseResult<String> updatePassword(UpdatePasswordReqDTO in) {
        if (in == null) {
            return ResponseResult.parameterError(null, "参数错误");
        }
        if (StringUtils.isBlank(in.getUserId())) {
            return ResponseResult.parameterError(null, "登录失效！");
        }
        if (StringUtils.isBlank(in.getOldPassword())) {
            return ResponseResult.parameterError(null, "旧密码不能为空");
        }
        if (StringUtils.isBlank(in.getNewPassword())) {
            return ResponseResult.parameterError(null, "新密码不能为空");
        }
        SysUser user = this.baseMapper.selectById(in.getUserId());
        if (user == null) {
            return ResponseResult.unauthorized(null, "用户不存在！");
        }
        if (!PasswordUtil.verifyPassword(in.getOldPassword(), user.getPasswordHash())) {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "旧密码错误！", null);
        }
        user.setPasswordHash(PasswordUtil.hashPassword(in.getNewPassword()));
        if (this.baseMapper.updateById(user) > 0) {
            return ResponseResult.ok("密码修改成功！");
        } else {
            return ResponseResult.failure(ResponseCode.INTERNAL_ERROR, "密码修改失败！", null);
        }
    }

    /**
     * 检查用户是否存在
     *
     * @param userName 用户名
     * @return
     */
    @Override
    public Boolean queryAccountExist(String userName) {
        Long user = this.baseMapper.selectCount(new QueryWrapper<SysUser>().eq("username", userName));
        if (user == null || user <= 0) {
            return false;
        } else {
            return true;
        }
    }

    //初始化管理员账号
    @Override
    public void initAdminAccount() {

        SysUser admin = new SysUser();
        admin.setUsername("admin");
        admin.setPasswordHash(PasswordUtil.hashPassword("huaxinai@1234."));
        admin.setEmail("qingshengfuai@163.com");
        admin.setRealName("管理员");
        admin.setStatus(1);
        admin.setPhone("13800000000");
        admin.setCreatedAt(LocalDateTime.now());
        admin.setCreatedBy("system");
        admin.setRoleId("admin");
        this.save(admin);
    }
}
